home *** CD-ROM | disk | FTP | other *** search
/ FM Towns: Free Software Collection 10 / FM Towns Free Software Collection 10.iso / ms_dos / lib / happysrc / paasm.c < prev    next >
Text File  |  1994-11-13  |  26KB  |  717 lines

  1. /**********************************************************************
  2.  *
  3.  *       *** HAPPy Pascal Compiler ***
  4.  *               P-code assmebler
  5.  *
  6.  *           Copyright (c) H.Asano 1992-1994.
  7.  *
  8.  **********************************************************************/
  9.  
  10. #define EXTERN extern
  11. #define Maxlabel   500                  /* 最大ラベル数               */
  12.  
  13. #include <stdio.h>
  14. #include <string.h>
  15. #include <stdlib.h>
  16. #include "version.h"
  17. #include "hapai.h"
  18.  
  19. /********* co-operation table **********/
  20. static char cop[] = {
  21.     115/*lod*/, 105/*ldo*/, 125/*str*/, 120/*sro*/,
  22.     130/*sto*/, 110/*chk*/, 135/*ind*/ } ;
  23.  
  24. /***************************************/
  25. /*            ラベル表                 */
  26. /***************************************/
  27. enum lbst {  entered,                   /* ラベル未登録の状態         */
  28.              defined                    /* ラベル定義済の状態         */
  29.           };
  30.  
  31. static struct  {
  32.   short     val         ;               /* value                      */
  33.   enum lbst st          ;               /* status {enterd,defined}    */
  34. } labeltab[Maxlabel]    ;
  35.  
  36. /***************************************/
  37. /*      仮想計算機 記憶装置            */
  38. /***************************************/
  39. static _store store[Maxstore] ;
  40.  
  41. /***************************************/
  42. /*            変数定義                 */
  43. /***************************************/
  44. static char *PcodeSourceName ;          /* P-codeソースファイル名      */
  45. static char *PcodeObjectName ;          /* P-codeオブジェクトファイル名       */
  46. static char *CompVersion     ;          /* コンパイラのバージョン     */
  47. static FILE *pcsfile         ;          /* P-codeソースファイルポインタ         */
  48. static FILE *objfile         ;          /* P-codeオブジェクトファイルポインタ    */
  49. static short codesize        ;          /* コードのワードサイズ           */
  50. static short objsize         ;          /* オブジェクト全体のワードサイズ */
  51. static short ch              ;          /* 読込文字                   */
  52. static short intch           ;          /* 読込処理内での読込文字     */
  53. static short  pc             ;          /* program counter            */
  54. static _code  cd             ;          /* P-code                     */
  55. static short entpc           ;          /* ent命令の番地              */
  56. static short start = -1      ;          /* オブジェクト開始の合図     */
  57.  
  58. /*********************************************************************/
  59.  
  60. /***************************************/
  61. /*     エラーメッセージ出力処理        */
  62. /***************************************/
  63. static void paerr(short errno)
  64. {
  65.   static struct _errmsg {
  66.        short msgno       ;              /* error message number       */
  67.        char  *errmsg     ;              /* error message              */
  68.      } errtb[]  =  {
  69.  
  70.    {1,  "命令数が多すぎる"},
  71.    {2,  "オブジェクトファイルがオープンできない"},
  72.    {3,  "オブジェクトファイル出力でエラーが発生した"},
  73.    {4,  "ラベルが多する"},
  74.    {5,  "定数が多すぎる"},
  75.    {6,  "P-codeソースファイルがオープンできない"},
  76.    {7,  "PC.EXEとPA.OVLのバージョンが違う"},
  77.    {8,  "アセンブルリストの出力でエラーが発生した"}
  78. } ;
  79.   short i = -1 ;
  80.  
  81.      while(errtb[++i].msgno != errno) ; /* search message             */
  82.      fprintf(stderr,"A%03d: %s\n", errno, errtb[i].errmsg);
  83.      exit(3) ;                          /* アセンブルエラーで停止     */
  84. }
  85.  
  86. /***************************************/
  87. /*      reset() : reset関数            */
  88. /***************************************/
  89. static void reset(char *filename)
  90. {
  91.  
  92.      pcsfile = fopen(filename,"r") ;
  93.      if(pcsfile == NULL) paerr(6) ;
  94.  
  95.      intch =  getc(pcsfile)  ;          /* 1文字先読み                */
  96. }
  97.  
  98. /***************************************/
  99. /*       eoln() : eolnマクロ定義       */
  100. /***************************************/
  101. #define eoln()   (intch == '\n')        /* 改行を読んでいれば真       */
  102.  
  103. /***************************************/
  104. /* readc() : char型read処理            */
  105. /***************************************/
  106. static short readc(void)
  107. {
  108.   short oldch ;
  109.  
  110.      oldch    = intch         ;
  111.      intch    = getc(pcsfile) ;
  112.      return(oldch)      ;
  113. }
  114.  
  115. /***************************************/
  116. /*   readi() : integer型入力処理       */
  117. /***************************************/
  118. static integer readi(void)
  119. {
  120.   integer  ival = 0 ;
  121.   short    sign = 1 ;
  122.  
  123.      if(intch == ' ')
  124.       while((intch = getc(pcsfile)) == ' '); /* 空白読み飛ばし        */
  125.  
  126.      if(intch=='-') {                    /* 符号の時 ( + は現れない)  */
  127.       sign = -1              ;           /* 符号に応じた正負          */
  128.       intch  = getc(pcsfile) ;           /* 符号を読み飛ばす          */
  129.      }
  130.  
  131.      do {
  132.       ival = ival*10 + intch-'0' ;
  133.       intch=getc(pcsfile) ;
  134.      } while(('0' <= intch) && (intch <= '9')) ;
  135.  
  136.      return(sign*ival) ;
  137. }
  138.  
  139. /***************************************/
  140. /*   readr() : real型入力処理          */
  141. /***************************************/
  142. static float readr(void)
  143. {
  144.   char   buf[20] ;
  145.   short  i = 0   ;
  146.  
  147.      while(intch == ' ') intch = getc(pcsfile) ;   /* 空白読み飛ばし */
  148.      do {
  149.       buf[i++] = (char)intch ;
  150.       intch = getc(pcsfile) ;
  151.      } while (intch != '\n') ;
  152.      buf[i] = '\0' ;
  153.  
  154.      return((float)atof(buf)) ;         /* 浮動小数点へ変換           */
  155. }
  156.  
  157. /***************************************/
  158. /* readln() : EOLまで読み飛ばす処理    */
  159. /***************************************/
  160. static void readln(void)
  161. {
  162.      while(!eoln()) intch = getc(pcsfile) ;
  163.      intch = getc(pcsfile);
  164. }
  165.  
  166. /***************************************/
  167. /*    オブジェクトファイル書出処理     */
  168. /***************************************/
  169. static void putobject(char *area, short size)
  170. {
  171.       fwrite(area,size,1,objfile) ;
  172.       if(ferror(objfile)) paerr(3) ;    /* 書き込み失敗               */
  173. }
  174.  
  175. /***************************************/
  176. /*          初期設定処理               */
  177. /***************************************/
  178. static void init(void)
  179. {
  180.   short i;
  181.  
  182.      for(i=0;i<Maxlabel;i++) {          /* ラベル表 の 初期設定       */
  183.       labeltab[i].val = -1 ;
  184.       labeltab[i].st  = entered;
  185.      }
  186.  
  187.      reset(PcodeSourceName) ;           /* P-codeソースファイルのオープン       */
  188.  
  189.      objfile = fopen(PcodeObjectName,"wb") ;/* ファイルオープン       */
  190.      if(objfile == NULL) paerr(2) ;     /* オープンできない           */
  191.  
  192.      if(codesize > Maxstore)            /* 記憶装置の大きさより大きい時*/
  193.       paerr(1) ;                        /* プログラム停止                */
  194.  
  195.      if(strcmp(CompVersion,version))
  196.       paerr(7) ;                        /* バージョン不一致           */
  197.  
  198.      putobject(version,strlen(version)+1) ; /* バージョン番号書出     */
  199.  
  200.      objsize = codesize ;
  201. }
  202.  
  203. /***************************************/
  204. /*    ラベル表登録処理                 */
  205. /***************************************/
  206. static void update(void)
  207. {
  208.    short x         ;                    /*  x: label名                */
  209.    short curr,succ ;
  210.  
  211.      x=(short)readi()           ;       /* ラベル名を読む             */
  212.      if(x >= Maxlabel) paerr(4) ;       /* ラベル数が多すぎる         */
  213.  
  214.      if(labeltab[x].val != -1) {        /* 前方参照されている時       */
  215.       curr = labeltab[x].val;
  216.       do {
  217.        succ = store[curr].vo.q;
  218.        store[curr].vo.q = pc  ;
  219.        curr = succ ;
  220.       } while(succ != -1) ;
  221.      }
  222.      labeltab[x].st  = defined    ;
  223.      labeltab[x].val = pc         ;
  224. }
  225.  
  226. /***************************************/
  227. /*     ラベル値読込処理                */
  228. /***************************************/
  229. static void labelsearch(void)
  230. {
  231.   short x ;
  232.  
  233.      while(ch != 'L') ch = readc() ;    /* 'L' まで 読み飛ばし        */
  234.      x = (short)readi() ;
  235.      if(x >= Maxlabel) paerr(4) ;       /* ラベル数が多すぎる         */
  236.      if(labeltab[x].st == entered) {    /* 未定義                     */
  237.       cd.q = labeltab[x].val  ;         /* 初期値のまま -1           */
  238.       labeltab[x].val = pc    ;         /* 今のpcを格納               */
  239.      }
  240.      else cd.q = labeltab[x].val ;      /* 定義済の時                 */
  241. }
  242.  
  243.  
  244. /********* typesymbol() : instruction名4文字目によってopを決定する *********/
  245. static void typesymbol(void)
  246. {
  247.    short i;
  248.  
  249.      switch(ch) {
  250.       case 'i' : return ;       /* 'i' の時は opはそのまま */
  251.       case 'a' : i=0; break;
  252.       case 'r' : i=1; break;
  253.       case 's' : i=2; break;
  254.       case 'b' : i=3; break;
  255.       case 'c' : i=4;
  256.      }
  257.      cd.op=cop[cd.op]+i;             /* opの変更 */
  258. }
  259.  
  260. /**************************************/
  261. /* PTN0() : オペランドのない命令      */
  262. /**************************************/
  263. static void PTN0(void)
  264. {
  265. }
  266.  
  267. /**************************************/
  268. /* PTN1() : lod,strのアセンブル       */
  269. /**************************************/
  270. static void PTN1(void)
  271. {
  272.      typesymbol() ;
  273.      cd.p=(char)readi() ;
  274.      cd.q=(short)readi() ;
  275. }
  276.  
  277. /**************************************/
  278. /* PTN2() : lda,mov,wrsのアセンブル   */
  279. /**************************************/
  280. static void PTN2(void)
  281. {
  282.      cd.p=(char)readi() ;
  283.      cd.q=(short)readi() ;
  284. }
  285.  
  286. /*********************************************/
  287. /* PTN3() : mst,cui,bas,tra.mms,             */
  288. /*          eol,eof,pge,rln,rdc,rdi,rdr,tgt, */
  289. /*          tgt,tpt,trs,trw,wln,wrb,wrc,wrf, */
  290. /*          wri,wrr のアセンブル             */
  291. /*********************************************/
  292. static void PTN3(void)
  293. {
  294.      cd.p=(char)readi() ;
  295. }
  296.  
  297. /**************************************/
  298. /* PTN4() : cup,ejpのアセンブル       */
  299. /**************************************/
  300. static void PTN4(void)
  301. {
  302.      cd.p=(char)readi() ;
  303.      labelsearch();
  304. }
  305.  
  306. /************************************************/
  307. /* PTN5() : equ,neq,geq,grt,leq,lesのアセンブル */
  308. /************************************************/
  309. static void PTN5(void)
  310. {
  311.      switch(ch) {
  312.     /*case 'a' :     ; break ;   何もしない */
  313.       case 'i' : cd.p=1 ; break ;
  314.       case 'r' : cd.p=2 ; break ;
  315.       case 'b' : cd.p=3 ; break ;
  316.       case 's' : cd.p=4 ; break ;
  317.       case 'c' : cd.p=6 ; break ;
  318.       case 'm' : cd.p=5 ;
  319.                  cd.q=(short)readi() ;
  320.      }
  321. }
  322.  
  323. /**************************************/
  324. /* PTN6() : ldo,sro,indのアセンブル   */
  325. /**************************************/
  326. static void PTN6(void)
  327. {
  328.      typesymbol() ;
  329.      cd.q=(short)readi();
  330. }
  331.  
  332. /****************************************/
  333. /* PTN7() : inc,dec,nxt,nxdのアセンブル */
  334. /****************************************/
  335. static void PTN7(void)
  336. {
  337.      switch(ch) {
  338.     /*case 'a' :  cd.p=0;    break ;  何もしない */ /* inc,decのみ */
  339.       case 'i' :  cd.p=1;    break ;
  340.       case 'b' :  cd.p=3;    break ;
  341.       case 'c' :  cd.p=6;    break ;
  342.      }
  343.      cd.q = (short)readi() ;
  344. }
  345.  
  346. /****************************************/
  347. /* PTN8() : ujp,fjp,lapのアセンブル     */
  348. /****************************************/
  349. #define PTN8  labelsearch
  350.  
  351. /***************************************/
  352. /* PTN9() : lao,new,disのアセンブル    */
  353. /***************************************/
  354. static void PTN9(void)
  355. {
  356.      cd.q=(short)readi();
  357. }
  358.  
  359. /**************************************/
  360. /* ENT() : entのアセンブル            */
  361. /**************************************/
  362. static void ENT(void)
  363. {
  364.      entpc = pc ;
  365. }
  366.  
  367. /**************************************/
  368. /* CHK() : chkのアセンブル            */
  369. /**************************************/
  370. static void CHK(void)
  371. {
  372.    integer  lb,ub ;
  373.  
  374.      typesymbol() ;
  375.      cd.p = (char)readi() ;             /* チェック種別              */
  376.      lb = readi();                      /* 下限値                     */
  377.      ub = readi();                      /* 上限値                     */
  378.      if(objsize+1>=Maxstore) paerr(5) ; /* 定数格納不可               */
  379.      store[objsize  ].vi = lb ;
  380.      store[objsize+1].vi = ub ;
  381.      cd.q=codesize;
  382.      do {
  383.       cd.q++ ;
  384.      } while((store[cd.q-1].vi != lb) || (store[cd.q].vi != ub)) ;
  385.      if(cd.q   == objsize) objsize++   ;/* 最後に1つだけ定数追加の時  */
  386.      if(cd.q-1 == objsize) objsize += 2;/* 最後に2つの  対数追加の時  */
  387. }
  388.  
  389. /**************************************/
  390. /* IXA() : ixaのアセンブル            */
  391. /**************************************/
  392. static void IXA(void)
  393. {
  394.   integer low  ;
  395.   short   ixav ;
  396.  
  397.      low  = readi() ;                     /* 下限値                     */
  398.      ixav = (short)readi() ;              /* ixa値                      */
  399.      if(objsize+1>=Maxstore) paerr(5) ;   /* 定数格納不可               */
  400.      store[objsize  ].vi = low  ;
  401.      store[objsize+1].va = ixav ;         /*  2バイトエリアを使用       */
  402.      cd.q=codesize;
  403.      do {
  404.       cd.q++ ;
  405.      } while((store[cd.q-1].vi != low) || (store[cd.q].va != ixav)) ;
  406.      if(cd.q   == objsize) objsize++   ;/* 最後に1つだけ定数追加の時  */
  407.      if(cd.q-1 == objsize) objsize += 2;/* 最後に2つの  対数追加の時  */
  408. }
  409.  
  410. /**************************************/
  411. /* LCA() : lcaのアセンブル            */
  412. /**************************************/
  413. /* lca '文字列'\n という形式とする。最後が改行で終わる。最初の ' と
  414.   改行の前の ' は P-codeソースを読む人間にわかりやすいようについているだけ */
  415.  
  416. static void LCA(void)
  417. {
  418.      cd.q=objsize;
  419.      readc() ;                          /* 最初の ' を読み飛ばす      */
  420.      while(!eoln()) {                   /* 改行までの文字列を格納     */
  421.       if(objsize+1>=Maxstore) paerr(5); /* 定数格納不可               */
  422.       store[objsize++].vc = readc() ;
  423.      }
  424.      objsize-- ;                        /* 最後の ' を捨てる          */
  425. }
  426.  
  427. /**************************************/
  428. /*   checkConst() : 定数格納チェック  */
  429. /**************************************/
  430. static void checkConst(void)
  431. {
  432.      if(cd.q==objsize) {
  433.       if(objsize+1>=Maxstore) paerr(5); /* 定数格納不可               */
  434.       objsize++ ;
  435.      }
  436. }
  437.  
  438. /**************************************/
  439. /* LDC() : ldcのアセンブル            */
  440. /**************************************/
  441. static void LDC(void)
  442. {
  443.   integer inumber ;
  444.   float   rnumber ;
  445.   long    s       ;
  446.  
  447.      switch(ch) {
  448.       case 'i' : cd.p=1 ;               /* integer type               */
  449.                  inumber = readi() ;
  450.                  if(labs(inumber) < (long)Largeint)
  451.                   cd.q = (short)inumber;
  452.                  else {                 /* 大きな数の時               */
  453.                   cd.op = 66 ;          /* lci命令に変更              */
  454.                   store[objsize].vi = inumber ;
  455.                   cd.q = codesize ;
  456.                   while(store[cd.q].vi != inumber) cd.q++ ;
  457.                   checkConst() ;        /* 定数格納チェック           */
  458.                  }
  459.                  break ;
  460.  
  461.       case 'c' : cd.p=6 ;               /* char type                  */
  462.                  while(readc() != '\'');/*  最初の ' を見つける       */
  463.                  cd.q=readc() ;         /*  文字を読み込む            */
  464.                  break ;                /*  最後の ' は無視する       */
  465.  
  466.       case 'b' : cd.p=3;                /* boolean                    */
  467.                  cd.q=(short)readi() ;
  468.                  break;
  469.  
  470.       case 's' : cd.p = 4;              /* set type                   */
  471.                  s=0;
  472.                  while(readc() != '(') ;
  473.                  while(readc() != ')') addset(s,(short)readi())  ;
  474.                  store[objsize].vs = s ;
  475.                  cd.q = codesize ;
  476.                  while(store[cd.q].vs != s) cd.q++ ;
  477.                  checkConst() ;         /* 定数格納チェック           */
  478.                  break ;
  479.  
  480.       case 'r' : cd.p = 2 ;
  481.                  rnumber = readr() ;
  482.                  store[objsize].vr = rnumber ;
  483.                  inumber = store[objsize].vi ;
  484.                  /* 浮動小数点の形で比較を行うと思わぬ落とし穴があるので
  485.                    ビット列の比較をするために、union型のviから数を得る*/
  486.                  cd.q = codesize ;
  487.                  while(store[cd.q].vi != inumber) cd.q++ ;
  488.                  checkConst() ;         /* 定数格納チェック           */
  489.                  break ;
  490.  
  491.     /*case 'n' : cd.p=0 ; */            /* ldc nil                    */
  492.               /* cd.q=0 ; */
  493.      }
  494. }
  495.  
  496. /**************************************/
  497. /* ORD() : ordのアセンブル            */
  498. /**************************************/
  499. static void ORD(void)
  500. {
  501.      switch(ch) {
  502.       case 'b' : cd.p=3 ; break ;
  503.       case 'c' : cd.p=6 ;
  504.      }
  505. }
  506.  
  507. /**************************************/
  508. /* RET() : retのアセンブル            */
  509. /**************************************/
  510. static void RET(void)
  511. {
  512.      switch(ch) {
  513.     /*case 'p' :     ; break ;  何もしない */
  514.       case 'i' : cd.p=1 ; break ;
  515.       case 'r' : cd.p=2 ; break ;
  516.       case 'c' : cd.p=3 ; break ;
  517.       case 'b' : cd.p=4 ; break ;
  518.       case 'a' : cd.p=5 ; break ;
  519.      }
  520. }
  521.  
  522. /**************************************/
  523. /* STO() : stoのアセンブル            */
  524. /**************************************/
  525. #define STO  typesymbol
  526.  
  527. /**********************************************************************/
  528. /*                   P-code ニーモニック表                            */
  529. /**********************************************************************/
  530. static char instr[][4] =
  531. {
  532.    /*          x0    x1    x2    x3    x4    x5    x6    x7    x8    x9  */
  533.    /* 0x */  "lod","ldo","str","sro","sto","chk","ind","ldc","lda","dec",
  534.    /* 1x */  "inc","mst","cup","ent","ret","...","ixa","equ","neq","geq",
  535.    /* 2x */  "grt","leq","les","ujp","fjp","xjp","ejp","lap","adi","adr",
  536.    /* 3x */  "sbi","sbr","sgs","flt","flo","trc","ngi","ngr","sqi","sqr",
  537.    /* 4x */  "abi","abr","not","and","ior","dif","int","uni","inn","mod",
  538.    /* 5x */  "odd","mpi","mpr","dvi","dvr","mov","lca","lao","stp","ord",
  539.    /* 6x */  "chr","ujc","mms","msi","cui","bas","...","cka","tra","rou",
  540.    /* 7x */  "nxt","nxd","...","...","...","new","dis","pge","eof","eol",
  541.    /* 8x */  "rst","rwt","get","put","wrs","wrb","wri","wrr","wrc","wrf",
  542.    /* 9x */  "wln","rdi","rdr","rdc","rln","trs","trw","tgt","tpt","atn",
  543.    /*10x */  "sin","cos","exp","log","sqt"
  544. } ;
  545.  
  546. /******* ニーモニック対応のエントリ表 ********/
  547. static struct entry {
  548.        void (*func)(void) ;
  549. } OP[] = {
  550.    /*          x0    x1    x2    x3    x4    x5    x6    x7    x8    x9  */
  551.    /* 0x */   PTN1, PTN6 ,PTN1, PTN6, STO , CHK , PTN6, LDC , PTN2, PTN7,
  552.    /* 1x */   PTN7, PTN3, PTN4, ENT , RET , PTN0, IXA , PTN5, PTN5, PTN5,
  553.    /* 2x */   PTN5, PTN5, PTN5, PTN8, PTN8, PTN0, PTN4, PTN8, PTN0, PTN0,
  554.    /* 3x */   PTN0, PTN0, PTN0, PTN0, PTN0, PTN0, PTN0, PTN0, PTN0, PTN0,
  555.    /* 4x */   PTN0, PTN0, PTN0, PTN0, PTN0, PTN0, PTN0, PTN0, PTN0, PTN0,
  556.    /* 5x */   PTN0, PTN0, PTN0, PTN0, PTN0, PTN2, LCA , PTN9, PTN0, ORD ,
  557.    /* 6x */   PTN0, PTN0, PTN3, PTN0, PTN3, PTN3, PTN0, PTN0, PTN3, PTN0,
  558.    /* 7x */   PTN7, PTN7, PTN0, PTN0, PTN0, PTN9, PTN9, PTN3, PTN3, PTN3,
  559.    /* 8x */   PTN0, PTN0, PTN0, PTN0, PTN2, PTN3, PTN3, PTN3, PTN3, PTN3,
  560.    /* 9x */   PTN3, PTN3, PTN3, PTN3, PTN3, PTN3, PTN3, PTN3, PTN3, PTN0,
  561.    /*10x */   PTN0, PTN0, PTN0, PTN0, PTN0
  562. } ;
  563.  
  564. /***************************************/
  565. /*     1行アセンブル処理               */
  566. /***************************************/
  567. static void assemble(void)
  568. {
  569.    char name[4];
  570.  
  571.      *name     = (char)readc()  ;       /* 1文字目 */
  572.      *(name+1) = (char)readc()  ;       /* 2文字目 */
  573.      *(name+2) = (char)readc()  ;       /* 3文字目 */
  574.      *(name+3) = '\0'     ;
  575.      if(!eoln()) ch=readc();
  576.       /* そこで行が終わってなければ次の文字を読む */
  577.  
  578.      cd.op = -1 ;
  579.      while(strcmp(instr[++cd.op],name)) ;/* instructionよりopを決定   */
  580.          /* このようなリニアサーチはスピードが遅いので改良しよう      */
  581.  
  582.      cd.p   =  0 ;
  583.      cd.q   =  0 ;
  584.      OP[cd.op].func() ;                 /* opに対応したアセンブル     */
  585.  
  586.      store[pc++].vo = cd ;              /* メモリに格納               */
  587. }
  588.  
  589. /********** generate() :  行の最初に呼ばれる処理 **********/
  590. static void generate(void)
  591. {
  592.    short i     ;                        /* 作業カウンタ               */
  593.    char progname[33] ;                  /* プログラム名               */
  594.    char filename[33] ;                  /* ファイル名                 */
  595.    short fileadr       ;                /* ファイルアトレス           */
  596.    short filesize      ;                /* バッファ変数の大きさ       */
  597.  
  598.      for(;;) {
  599.       ch=readc();                       /* 行の最初の文字を読む       */
  600.       switch(ch) {
  601.        case ' ' : assemble();           /* 通常命令 その行をアセンブル*/
  602.                   break     ;
  603.  
  604.        case ';' :                       /* 注釈行を無視               */
  605.                   break ;
  606.  
  607.        case 'L' : update()  ;           /* label登録                  */
  608.                   break ;
  609.  
  610.        case 'V' : store[entpc].vo.p = (unsigned char)readi() ;
  611.                   store[entpc].vo.q = (short)        readi() ;
  612.                   break ;
  613.  
  614.        case 'F' :                       /* ファイルアドレス           */
  615.                   readc() ;             /* 空白を読み飛ばす           */
  616.                   i=0 ;
  617.                   while((ch=readc()) != ' ') /* ファイル名取得        */
  618.                    filename[i++] = (char)ch ;
  619.                   filename[i++] = '\0'  ;
  620.                   readc() ;                       /*  空白を読み飛ばす*/
  621.                   fileadr = (short)readi() ;      /* ファイルアトレス */
  622.                   putobject((char*)&fileadr,sizeof(fileadr));/* 書出  */
  623.                   filesize = (short)readi();      /* バッファサイズ   */
  624.                   putobject((char*)&filesize,sizeof(filesize));/* 書出*/
  625.                   putobject(filename,i) ;         /* ファイル名書出   */
  626.                   break ;
  627.  
  628.        case 'N' :                       /* プログラム名               */
  629.                   readc() ;             /* 空白を読み飛ばす           */
  630.                   i=0 ;
  631.                   while(!eoln())        /* プログラム名取得           */
  632.                    progname[i++] = (char)readc() ;
  633.                   progname[i++] = '\0' ;
  634.                   putobject(progname,i);/* 書出                       */
  635.                   break ;
  636.  
  637.        case 'Q' : return ;              /* アセンブル終わり           */
  638.       }
  639.       readln() ;                        /* 行の残りを読み飛ばし       */
  640.      }
  641. }
  642.  
  643.  
  644. /*****************************************/
  645. /* assemblelist() : アセンブルリスト出力 */
  646. /*****************************************/
  647. static void assemblelist(void)
  648. {
  649.      reset(PcodeSourceName) ;           /* P-codeソースファイルのオープン       */
  650.  
  651.      printf("\n ADDR   OP   P      Q    P-code source statement\n");
  652.      printf(  "================================================\n");
  653.  
  654.      pc  = 0 ;
  655.  
  656.      for(;;) {
  657.       ch=readc();                       /* 行の最初の文字             */
  658.       switch(ch) {
  659.        case ' ' :  printf(" %4d: %3d %3d %6d    %c",
  660.                      pc++, store[pc].vo.op, store[pc].vo.p ,
  661.                      store[pc].vo.q,ch);
  662.                    break;
  663.        case ';' :
  664.        case 'L' :
  665.        case 'V' :
  666.        case 'F' :
  667.        case 'N' :  printf("\t\t\t %c",ch) ;
  668.                    break;
  669.        case 'Q' :  printf("\t\t\t Q\n") ;
  670.                    if(codesize != objsize)
  671.                    printf(" %4d:\n   ~: constant data\n %4d:\n",
  672.                      codesize,objsize-1) ;
  673.                    fclose(pcsfile) ;   /* ソースファイルのクローズ   */
  674.                    return;
  675.       }
  676.       while(!eoln()) putc(readc(),stdout) ;
  677.       printf("\n") ;
  678.       if(ferror(stdout)) paerr(8) ;     /* 出力でエラーが発生した     */
  679.       readln()     ;
  680.      }
  681. }
  682.  
  683. /***************************************/
  684. /* main() : P-codeアセンブラメイン処理 */
  685. /***************************************/
  686. short main(short argc,char *argv[])
  687. {
  688.      codesize  = atoi(argv[1]) ;        /* 命令コードの数             */
  689.      PcodeSourceName = argv[2] ;        /* P-codeソースファイル名     */
  690.      PcodeObjectName = argv[3] ;        /* P-codeオブジェクトファイル名*/
  691.      CompVersion     = argv[4] ;        /* コンパイラのバージョン     */
  692.      init();                            /* 各種初期設定               */
  693.      generate();                        /* アセンブル                 */
  694.      fclose(pcsfile)  ;                 /* ソースファイルのクローズ   */
  695.  
  696.      for(pc=0;pc<codesize;pc++) {       /* qオペランドの補正処理         */
  697.       cd.op = store[pc].vo.op ;
  698.       if((/*lao*/ cd.op==57)||(/*ldox*/cd.op==1 || (105<=cd.op && cd.op<=109))
  699.                             ||(/*srox*/cd.op==3 || (120<=cd.op && cd.op<=124)))
  700.        store[pc].vo.q += objsize ;
  701.      }
  702.  
  703.      putobject((char*)&start,sizeof(start)) ; /* オブジェクト開始合図 */
  704.      putobject((char*)store,objsize*sizeof(_store)) ; /* オブジェクト出力*/
  705.      if(fflush(objfile) == EOF) paerr(3) ;
  706.      if(fclose(objfile) == EOF) paerr(3) ;
  707.                  /* クローズできなければ書き込み失敗の可能性がある    */
  708.  
  709.      fputs(         " *** Assemble completed. ***\n",stderr);
  710.      fprintf(stderr," *** code = %5d words  constant data = %5d words ***\n",
  711.                                 codesize,       objsize-codesize);
  712.  
  713.      if(argc==6) assemblelist();        /* アセンブルリストの出力     */
  714.  
  715.      return(0) ;                        /* 正常終了                   */
  716. }
  717.